/* 二分图
* 1.二分图、不存在奇数环、染色法不存在矛盾
* 2.匈牙利算法，匹配、最大匹配、匹配点、增广路径
* 3.最小点覆盖、最大独立集、最小路径点覆盖(最小路径重复点覆盖)
    最大匹配数 = 最小点覆盖 = 总点数-最大独立集 = 总点数-最小路径点覆盖

* 本题: 最多取多少条边, 所有选出的边无公共点
*/

#pragma GCC optimize("O1,O2,O3,Ofast")
#pragma GCC optimize("no-stack-protector,unroll-loops,fast-math,inline")
#pragma GCC target("avx,avx2,fma")
#pragma GCC target("sse,sse2,sse3,sse4,sse4.1,sse4.2,ssse3")

#include<iostream>
#include<cstring>
#include<algorithm>
// #define ONLINE_GUDGE
using namespace std;
using PII = pair<int, int>;
#define x first 
#define y second 
const int N = 110, INF = 0x3f3f3f3f;
const int dx[4] = {-1,  0,  1,  0}, 
          dy[4] = { 0,  1,  0, -1};
int n, m;
bool g[N][N], st[N][N];
PII match[N][N];


bool find(int x, int y)
{
    for(int k = 0; k < 4; k++)
    {
        int nx = x + dx[k], ny = y + dy[k];
        if(nx < 1 || nx > n || ny < 1 || ny > n) continue;
        if(st[nx][ny] || g[nx][ny]) continue;

        st[nx][ny] = true;
        PII t = match[nx][ny]; // 邻边的匹配点
        if(t.x == -1 || find(t.x, t.y)) // 邻边无匹配 or 邻边有解
        {
            match[nx][ny] = {x, y}; // (x,y)和(nx,ny)摆放骨牌
            return true;
        }
    }
    return false;
}

int main()
{

    #ifdef ONLINE_JUDGE

    #else
    freopen("./in.txt","r",stdin);
    #endif
    ios::sync_with_stdio(false);   
	cin.tie(0);
    
    cin >> n >> m;

    while(m--)
    {
        int x, y; cin >> x >> y;
        g[x][y] = true;
    }

    memset(match, -1, sizeof match);

    int res = 0;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
            if((i+j) % 2 && !g[i][j]) // 枚举所有和为奇数的点, 全部枚举一定有一半不可摆放, 规定从和为奇数点开始摆放
            {
                memset(st, 0, sizeof st);         
                if(find(i, j)) res++;
            }

    cout << res << endl;
    return 0;
}